from django.shortcuts import render
from QQLoginTool.QQtool import OAuthQQ
# Create your views here.
from rest_framework.response import Response
from rest_framework.views import APIView
# 导入可以获取配置文件中的所有属性包settings
from django.conf import settings
from rest_framework.generics import CreateAPIView
from  itsdangerous import  TimedJSONWebSignatureSerializer as TJS


from rest_framework_jwt.settings import api_settings

from carts.utils import merge_cart_cookie_to_redis
from oauth.models import OAuthQQUser
from oauth.serializers import QQAuthUserSerializer


# QQ登陆第一步：获取跳转到qq服务器的链接
class QQAuthURLView(APIView):
    def get(self, request):
        # 获取前端传递的state
        # state表示从哪个页面进入到的登录页面，将来登录成功后，就自动回到那个页面
        state = request.query_params.get('state', None)
        if not state:
            state = '/'
        # 1初始化OAuthQQ对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI, state=state)
        # 2.获取QQ登录扫码页面，扫码后得到Authorization Code
        login_url = oauth.get_qq_url()

        # 返回结果
        return Response({'login_url': login_url})


# QQ登陆第二步
class QQAuthUserView(CreateAPIView):

    # 指定序列化器（qq登陆第三步）
    serializer_class = QQAuthUserSerializer

    def get(self, request):
        # 1.获取code
        code = request.query_params.get('code', None)

        # 2.判断code是否存在
        if not code:
            return Response({'errors': '缺少code值'}, status=400)

        # 初始化OAuthQQ对象
        state = '/'
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI, state=state)
        # 3.根据code获取access_token
        try:
            access_token = oauth.get_access_token(code)

            # 4.根据asses_token获取openid
            openid = oauth.get_open_id(access_token)
        except Exception:
            return Response({'message': '服务器异常'}, status=500)

        # 5.判断openid是否绑定商城账号
        # 创建模型对象
        try:
            qq_user = OAuthQQUser.objects.get(openid=openid)
        except:
            # 如果openid没绑定美多商城用户，创建用户并绑定到openid
            # 为了能够在后续的绑定用户操作中前端可以使用openid，在这里将openid签名后响应给前端
            # 加密openid
            tjs=TJS(settings.SECRET_KEY,300)
            open_id=tjs.dumps({'openid':openid}).decode()

            return Response({'access_token': open_id})
        else:
            # openid已经绑定过商城账号，直接生成jJWT token  并返回
            user = qq_user.user
            # 生成jwt token
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)

        # 6.返回结果
        response = Response({
            'token': token,
            'username': user.username,
            'user_id': user.id
        })

        # 合并购物车
        response = merge_cart_cookie_to_redis(request, user, response)

        return response

    # 重写post方法，完成与购物车的合并
    def post(self, request, *args, **kwargs):
        response = super().post(request, *args, **kwargs)

        # 1.获取code
        code = request.query_params.get('code', None)

        # 2.判断code是否存在
        if not code:
            return Response({'errors': '缺少code值'}, status=400)

        # 初始化OAuthQQ对象
        state = '/'
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI, state=state)
        # 3.根据code获取access_token
        try:
            access_token = oauth.get_access_token(code)

            # 4.根据asses_token获取openid
            openid = oauth.get_open_id(access_token)
        except Exception:
            return Response({'message': '服务器异常'}, status=500)

        # 5.判断openid是否绑定商城账号
        # 创建模型对象
        try:
            qq_user = OAuthQQUser.objects.get(openid=openid)
        except:
            # 如果openid没绑定美多商城用户，创建用户并绑定到openid
            # 为了能够在后续的绑定用户操作中前端可以使用openid，在这里将openid签名后响应给前端
            # 加密openid
            tjs = TJS(settings.SECRET_KEY, 300)
            open_id = tjs.dumps({'openid': openid}).decode()

            return Response({'access_token': open_id})
        else:
            # openid已经绑定过商城账号，直接生成jJWT token  并返回
            user = qq_user.user

        # 合并购物车
        response = merge_cart_cookie_to_redis(request, user, response)
        return response
